<template>
  <div class="search-bar">
    <div
      class="fields-wrapper"
      :style="{ gridTemplateColumns: `repeat(${columns}, minmax(260px, 1fr))` }"
    >
      <div v-for="field in displayedFields" :key="field.prop" class="search-item">
        <label v-if="field.label" class="search-label">
          <span v-if="field.required" class="required">*</span>{{ field.label }}：
        </label>
        <!-- 输入框 -->
        <el-input
          v-if="field.type === 'input'"
          v-model="localModel[field.prop]"
          :placeholder="field.placeholder || t('common.pleaseEnter')"
          clearable
          :style="{ width: field.width || '250px' }"
          @change="handleChange"
        />
        <!-- 下拉选择 -->
        <el-select
          v-else-if="field.type === 'select'"
          v-model="localModel[field.prop]"
          :placeholder="field.placeholder || t('common.pleaseSelect')"
          clearable
          :style="{ width: field.width || '200px' }"
          @change="handleChange"
        >
          <el-option
            v-for="option in field.options"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
      </div>
    </div>
    <div class="search-actions">
      <el-button
        v-if="showToggle && fields.length > visibleCount"
        link
        type="primary"
        @click="expanded = !expanded"
      >
        {{ expanded ? t('common.collapse') || '收起' : t('common.expand') || '展开' }}
        <el-icon style="margin-left: 2px">
          <ArrowDown v-if="!expanded" />
          <ArrowUp v-else />
        </el-icon>
      </el-button>
      <el-button type="primary" @click="handleSearch">{{ t('common.search') }}</el-button>
      <el-button @click="handleReset">{{ resetText || t('common.reset') }}</el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import { ElButton, ElInput, ElSelect, ElOption, ElIcon } from 'element-plus'
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'

interface SearchField {
  prop: string // 字段名
  label?: string // 标签文本
  type: 'input' | 'select' // 类型
  placeholder?: string // 占位符
  width?: string // 宽度
  options?: { label: string; value: any }[] // 下拉选项
  required?: boolean // 是否必填（仅用于显示*）
}

interface Props {
  fields: SearchField[] // 搜索字段配置
  modelValue?: Record<string, any> // 双向绑定的搜索参数
  resetText?: string // 重置按钮文本
  columns?: number // 每行展示列数
  visibleCount?: number // 收起时显示的字段数
  showToggle?: boolean // 是否显示展开/收起
  // 国际化函数
  t?: (key: string) => string
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => ({}),
  resetText: '',
  columns: 3,
  visibleCount: 3,
  showToggle: false,
  t: (key: string) => {
    const translations: Record<string, string> = {
      'common.pleaseEnter': '请输入',
      'common.pleaseSelect': '请选择',
      'common.search': '搜索',
      'common.reset': '重置',
      'common.collapse': '收起',
      'common.expand': '展开',
    }
    return translations[key] || key
  },
})

const emit = defineEmits<{
  (e: 'update:modelValue', value: Record<string, any>): void
  (e: 'search', value: Record<string, any>): void
  (e: 'reset'): void
}>()

// 本地模型
const localModel = ref<Record<string, any>>({ ...props.modelValue })
const expanded = ref(false)
const columns = computed(() => props.columns)
const visibleCount = computed(() => props.visibleCount)

const displayedFields = computed(() => {
  if (props.showToggle && !expanded.value && props.fields.length > visibleCount.value) {
    return props.fields.slice(0, visibleCount.value)
  }
  return props.fields
})

// 监听外部变化
watch(
  () => props.modelValue,
  (newVal) => {
    localModel.value = { ...newVal }
  },
  { deep: true }
)

// 处理变化
const handleChange = () => {
  emit('update:modelValue', localModel.value)
}

// 搜索
const handleSearch = () => {
  emit('search', localModel.value)
}

// 重置
const handleReset = () => {
  const resetData: Record<string, any> = {}
  props.fields.forEach((field) => {
    resetData[field.prop] = ''
  })
  localModel.value = resetData
  emit('update:modelValue', resetData)
  emit('reset')
}

const t = props.t || ((key: string) => key)
</script>

<style scoped lang="scss">
.search-bar {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 16px 20px;
  margin-bottom: 16px;
  box-shadow: none;

  .fields-wrapper {
    display: grid;
    gap: 12px 24px;
    flex: 1;
  }

  .search-item {
    display: flex;
    align-items: center;

    .search-label {
      margin-right: 8px;
      width: 64px;
      white-space: nowrap;
      color: #606266;
      font-size: 14px;
    }

    .required {
      color: var(--el-color-danger);
      margin-right: 2px;
    }
  }

  .search-actions {
    display: flex;
    gap: 8px;
    margin-left: auto;
    align-items: center;
  }
}
</style>
